import { observe } from './Observer.js'
import { Watcher } from './Watcher.js'

export default class MyVue {
  // 构造函数传入一个对象作为配置项
  constructor(options = {}) {
    this.$options = options;
    this.$el = document.querySelector(this.$options.el);
    // 简化对 data 的处理，使用 _data 存储 vue 实例的 data，再赋值给 data 变量
    let data = (this._data = this.$options.data)
    // 所有data最外层属性代理到Vue实例上
    Object.keys(data).forEach(key => this._proxy(key))
    // 把 data 转换成响应式对象
    observe(data)
  }

  // 对外暴露依赖(订阅者)的接口，用于监听对象
  $watch(expOrFn, cb) {
    new Watcher(this, expOrFn, cb)
  }

  // 代理函数
  _proxy(key) {
    Object.defineProperty(this, key, {
      configurable: true,
      enumerable: true,
      get: () => this._data[key],
      set: val => {
        this._data[key] = val
      } 
    })
  }
}